Word Pattern II

Given a pattern and a string str, find if str follows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty substring in str.

Examples:

  1. pattern = "abab", str = "redblueredblue" should return true.
  2. pattern = "aaaa", str = "asdasdasdasd" should return true.
  3. pattern = "aabb", str = "xyzabcxzyabc" should return false.

Notes:
You may assume both pattern and str contains only lowercase letters.

Solution:

  1. public class Solution {
  2. public boolean wordPatternMatch(String pattern, String str) {
  3. Map<Character, String> map = new HashMap<>();
  4. Set<String> set = new HashSet<>();
  5. return isMatch(str, 0, pattern, 0, map, set);
  6. }
  7. boolean isMatch(String str, int i, String pat, int j, Map<Character, String> map, Set<String> set) {
  8. // base case
  9. if (i == str.length() && j == pat.length()) return true;
  10. if (i == str.length() || j == pat.length()) return false;
  11. // get current pattern character
  12. char c = pat.charAt(j);
  13. // if the pattern character exists
  14. if (map.containsKey(c)) {
  15. String s = map.get(c);
  16. // then check if we can use it to match str[i...i+s.length()]
  17. if (!str.startsWith(s, i)) {
  18. return false;
  19. }
  20. // if it can match, great, continue to match the rest
  21. return isMatch(str, i + s.length(), pat, j + 1, map, set);
  22. }
  23. // pattern character does not exist in the map
  24. for (int k = i; k < str.length(); k++) {
  25. String p = str.substring(i, k + 1);
  26. if (set.contains(p)) {
  27. break;
  28. }
  29. // create or update it
  30. map.put(c, p);
  31. set.add(p);
  32. // continue to match the rest
  33. if (isMatch(str, k + 1, pat, j + 1, map, set)) {
  34. return true;
  35. }
  36. }
  37. // we've tried our best but still no luck
  38. // backtracking
  39. set.remove(map.get(c));
  40. map.remove(c);
  41. return false;
  42. }
  43. }